home *** CD-ROM | disk | FTP | other *** search
/ PC World Interactive 11 / PC World Interactive 11.iso / share / convert / dl2gl.arj / DLTOGL.C next >
C/C++ Source or Header  |  1991-11-06  |  9KB  |  414 lines

  1. /*
  2.  * dltogl.c -- convert .DL animations into .GL animations.
  3.  *
  4.  * usage: dltogl file.dl [file.gl]
  5.  *
  6.  * If no .gl file is specified, the images and control file will be
  7.  * written to separate files.  The control file will always be "dl.txt",
  8.  * the images "clpN.clp" and a palette file called "palette.pic".
  9.  *
  10.  * Author:
  11.  *      George Phillips
  12.  *      <phillips@cs.ubc.ca>
  13.  */
  14.  
  15. #include <stdio.h>
  16. #ifdef __TURBOC__
  17. #include <alloc.h>
  18. #else
  19. extern char* malloc();
  20. #endif
  21.  
  22. #define FOW     "wb"
  23.  
  24. FILE*   gl;
  25. int             gl_fileno;
  26.  
  27. FILE* file_open();
  28. int file_close();
  29.  
  30. #define isneg16(x)      ((x) & 0x8000)
  31. #define neg16(x)        ((~(x) + 1) & 0x7fff)
  32.  
  33. main(argc, argv)
  34. int             argc;
  35. char*   argv[];
  36. {
  37.     unsigned int i, j;
  38.     FILE* fp;
  39.     int num_scrn;
  40.     int ctl_len;
  41.     int ch;
  42.     int format;
  43.     static char title[21];
  44.     static char author[21];
  45.     static unsigned char pal[256*3];
  46.     unsigned char* screen;
  47.     static unsigned char halfscreen[160*100];
  48.     static char fname[32];
  49.     int picnum;
  50.     int images_per_screen;
  51.     FILE* ctl;
  52.     int fx, fy;
  53.     int* cmd;
  54.     int labelpos;
  55.     int cmdnum;
  56.  
  57.     if (argc != 2 && argc != 3)
  58.         die("usage: dltogl file.dl [file.gl]");
  59.  
  60.     if (!(fp = fopen(argv[1], "rb"))) {
  61.         fprintf(stderr, "dltogl: can't open %s\n", argv[1]);
  62.         exit(1);
  63.     }
  64.  
  65.     gl = 0;
  66.     gl_fileno = 0;
  67.     if (argc == 3 && !(gl = fopen(argv[2], FOW))) {
  68.         fprintf(stderr, "dltogl: can't open %s for writing\n", argv[2]);
  69.         exit(1);
  70.     }
  71.  
  72.     if (fgetc(fp) != 2)
  73.         die("dltogl: only version 2 files can be handled");
  74.  
  75.     switch (format = fgetc(fp)) {
  76.     case 0:
  77.         fx = fy = 0;
  78.         images_per_screen = 1;
  79.         break;
  80.     case 1:
  81.         fx = 80;
  82.         fy = 50;
  83.         images_per_screen = 4;
  84.         break;
  85.     default:
  86.         die("dltogl: only large and medium formats are handled");
  87.         break;
  88.     }
  89.  
  90.     title[20] = author[20] = 0;
  91.     for (i = 0; i < 20; i++)
  92.         title[i] = fgetc(fp) ^ 255;
  93.  
  94.     for (i = 0; i < 20; i++)
  95.         author[i] = fgetc(fp) ^ 255;
  96.  
  97.     for (i = 0; i < 20; i++) {
  98.         if ((unsigned char)title[i] == 255) title[i] = 0;
  99.         if ((unsigned char)author[i] == 255) author[i] = 0;
  100.     }
  101.  
  102.     num_scrn = fgetc(fp);
  103.     ctl_len = fgetc(fp);
  104.  
  105.     if (!(cmd = (int*)malloc(ctl_len * sizeof(int))))
  106.         die("dltogl: out of memory");
  107.  
  108.     gl_numfiles(num_scrn * images_per_screen + 1 + 1);
  109.  
  110.     /* mebbe this is the border colour? */
  111.     for (i = 0; i < 3; i++)
  112.         fgetc(fp);
  113.  
  114.     for (i = 0; i < 256; i++) {
  115.         pal[i*3] = fgetc(fp);
  116.         pal[i*3+1] = fgetc(fp);
  117.         pal[i*3+2] = fgetc(fp);
  118.     }
  119.  
  120.     if (!(screen = malloc(320 * 200)))
  121.         die("dltogl: not enough memory.");
  122.  
  123.     memset(screen, 0, 320 * 200);
  124.     writepic(screen, 320, 200, "palette.pic", pal);
  125.  
  126.     picnum = 0;
  127.     for (j = 0; j < num_scrn; j++) {
  128.         fread(screen, 320 * 200, 1, fp);
  129.         switch (format) {
  130.         case 0: /* large */
  131.             sprintf(fname, "clp%d.clp", picnum++);
  132.             writepic(screen, 320, 200, fname, (unsigned char*)0);
  133.             break;
  134.         case 1: /* medium */
  135.             for (i = 0; i < 4; i++) {
  136.                 unsigned char*  src;
  137.                 unsigned char*  dst;
  138.                 int                             row;
  139.                 int                             col;
  140.  
  141.                 sprintf(fname, "clp%d.clp", picnum++);
  142.                 src = screen + (i % 2) * 160 + (i / 2) * 100 * 320;
  143.                 dst = halfscreen;
  144.                 for (row = 0; row < 100; row++) {
  145.                     for (col = 0; col < 160; col++)
  146.                         *dst++ = *src++;
  147.                     src += 160;
  148.                 }
  149.                 writepic(halfscreen, 160, 100, fname, (unsigned char*)0);
  150.             }
  151.         }
  152.     }
  153.  
  154.     ctl = file_open("dl.txt", FOW);
  155.  
  156.     fprintf(ctl, "; This GL file was converted from DL format by dltogl\r\n");
  157.     fprintf(ctl, "; Title:  %s\r\n", title);
  158.     fprintf(ctl, "; Author: %s\r\n", author);
  159.     /* could print all the other keeno information */
  160.  
  161.     fprintf(ctl, "video l\r\n");
  162.     fprintf(ctl, "pload palette,1\r\n");
  163.     fprintf(ctl, "palette 1\r\n");
  164.     fprintf(ctl, "pfree 1\r\n");
  165.     for (i = 0; i < num_scrn * images_per_screen; i++)
  166.         fprintf(ctl, "cload clp%d,%d\r\n", i, i + 1);
  167.  
  168.     for (i = 0; i < ctl_len; i++) {
  169.         j = fgetc(fp);
  170.         j += fgetc(fp) << 8;
  171.         cmd[i] = j;
  172.     }
  173.  
  174.     labelpos = 0;
  175.     if (isneg16(cmd[ctl_len - 1])) {
  176.         labelpos = neg16(cmd[ctl_len - 1]) + 1;
  177.         ctl_len--;      /* ignore that last command */
  178.     }
  179.  
  180.     for (i = 0, cmdnum = 0; i < ctl_len; i++, cmdnum++) {
  181.         if (cmdnum == labelpos)
  182.             fprintf(ctl, "forever:\r\n");
  183.         if (isneg16(cmd[i])) {
  184.             i++;
  185.             fprintf(ctl, "waitkey %d\r\n", cmd[i]);
  186.         }
  187.         else
  188.             fprintf(ctl, "putup %d,%d,%d,10\r\n", fx, fy, cmd[i] + 1);
  189.     }
  190.     fprintf(ctl, "goto forever\r\n");
  191.     fputc(26, ctl);
  192.     file_close(ctl);
  193.  
  194.     fclose(fp);
  195.  
  196.     if (gl)
  197.         fclose(gl);
  198.  
  199.     exit(0);
  200. }
  201.  
  202. die(s)char*s;{fprintf(stderr,"%s\n",s);exit(1);}
  203.  
  204. #define BLOCKSIZE       (8192)
  205.  
  206. writepic(pixel, width, height, filename, cmap)
  207. unsigned char* pixel;
  208. int     width;
  209. int     height;
  210. char* filename;
  211. unsigned char* cmap;
  212. {
  213.     FILE*   fp;
  214.     unsigned int i;
  215.     static unsigned char buf[BLOCKSIZE];
  216.     unsigned char* p;
  217.     int row, col;
  218.  
  219.     fp = file_open(filename, FOW);
  220.  
  221.     /* write header */
  222.     writeshort(fp, 0x1234); /* magic number */
  223.     writeshort(fp, width);
  224.     writeshort(fp, height);
  225.     writeshort(fp, 0);
  226.     writeshort(fp, 0);
  227.     fputc(8, fp);                                           /* bits per pixel */
  228.     fputc(0xff, fp);                                        /* byte here is always 255 */
  229.     fputc('L', fp);                                         /* video mode */
  230.     if (cmap) {
  231.         writeshort(fp, 4);              /* extra information descriptor */
  232.         writeshort(fp, 768);    /* extra information length */
  233.         fwrite(cmap, 768, 1, fp);
  234.     }
  235.     else {
  236.         writeshort(fp, 0);
  237.         writeshort(fp, 0);
  238.     }
  239.  
  240.     /* number of packed blocks in file */
  241.     writeshort(fp, ((long)width * height + BLOCKSIZE - 1) / BLOCKSIZE);
  242.  
  243.     i = 0;
  244.     for (row = height - 1; row >= 0; row--) {
  245.         p = pixel + row * width;
  246.         for (col = 0; col < width; col++) {
  247.             buf[i++] = *p++;
  248.             if (i == BLOCKSIZE) {
  249.                 outpackblock(fp, buf, i);
  250.                 i = 0;
  251.             }
  252.         }
  253.     }
  254.     if (i > 0)
  255.         outpackblock(fp, buf, i);
  256.  
  257.     file_close(fp);
  258. }
  259.  
  260. outpackblock(fp, buf, len)
  261. FILE*   fp;
  262. char*   buf;
  263. int     len;
  264. {
  265.     static char     packbuf[BLOCKSIZE * 4 - 1];     /* overkill */
  266.     int     packlen;
  267.  
  268.     packlen = packblock(buf, packbuf, len);
  269.     fwrite(packbuf, packlen, 1, fp);
  270. }
  271.  
  272. packblock(src, dest, len)
  273. char*   src;
  274. char*   dest;
  275. int             len;
  276. {
  277.     unsigned char*  s;
  278.     unsigned char*  r;
  279.     unsigned char*  d;
  280.     static int      overhead[256];
  281.     int     i;
  282.     int     esc;
  283.     int     escpresent;
  284.     int     minover;
  285.     int     packlen;
  286.  
  287.     for (i = 0; i < 256; i++)
  288.         overhead[i] = 0;
  289.  
  290.     /* do first pass to find optimal esc byte */
  291.     for (s = src; s < src + len; s = r) {
  292.         for (r = s; *r == *s && r < src + len; r++)
  293.             ;
  294.         if (r - s < 4)
  295.             overhead[*s]++;
  296.     }
  297.  
  298.     minover = len + 1;
  299.     for (i = 0; i < 256; i++) {
  300.         if (overhead[i] < minover) {
  301.             minover = overhead[i];
  302.             esc = i;
  303.         }
  304.     }
  305.     escpresent = overhead[esc] == 0;
  306.  
  307.     /* now run-length encode on the second pass */
  308.  
  309.     d = dest + 5;
  310.     for (s = src; s < src + len; s = r) {
  311.         for (r = s; *r == *s && r < src + len; r++)
  312.             ;
  313.         if (r - s < 4 && (!escpresent || *s != esc)) {
  314.             while (s < r)
  315.                 *d++ = *s++;
  316.         }
  317.         else {
  318.             if (r - s > 255) {
  319.                 *d++ = esc;
  320.                 *d++ = 0;
  321.                 *d++ = (r - s) & 0xff;
  322.                 *d++ = ((r - s) >> 8) & 0xff;
  323.                 *d++ = *s++;
  324.             }
  325.             else {
  326.                 *d++ = esc;
  327.                 *d++ = r - s;
  328.                 *d++ = *s++;
  329.             }
  330.         }
  331.     }
  332.  
  333.     packlen = d - dest;
  334.  
  335.     /* fill in the block header */
  336.  
  337.     *dest++ = packlen & 0xff;                       /* packed block size */
  338.     *dest++ = ((packlen) >> 8) & 0xff;
  339.     *dest++ = len & 0xff;
  340.     *dest++ = (len >> 8) & 0xff;            /* unpacked block size */
  341.     *dest++ = esc;                                          /* escape byte */
  342.  
  343.     return packlen;
  344. }
  345.  
  346. writeshort(fp, s)
  347. FILE*   fp;
  348. int             s;
  349. {
  350.     fputc(s & 255, fp);
  351.     fputc((s >> 8) & 255, fp);
  352. }
  353.  
  354. writelong(fp, l)
  355. FILE*   fp;
  356. long    l;
  357. {
  358.     fputc(l & 255, fp);
  359.     fputc((l >> 8) & 255, fp);
  360.     fputc((l >> 16) & 255, fp);
  361.     fputc((l >> 24) & 255, fp);
  362. }
  363.  
  364. long gl_eof;
  365. long gl_filestart;
  366.  
  367. gl_numfiles(n)
  368. int     n;
  369. {
  370.     if (gl) {
  371.         fseek(gl, 0, 0);
  372.         writeshort(gl, n * 17);
  373.         gl_eof = 2 + n * 17;
  374.     }
  375. }
  376.  
  377. FILE* file_open(name, mode)
  378. char*   name;
  379. char*   mode;
  380. {
  381.     FILE*   fp;
  382.     char    fname[14];
  383.  
  384.     if (!gl) {
  385.         if (!(fp = fopen(name, mode))) {
  386.             fprintf(stderr, "dltogl: can't open %s\n", name);
  387.             exit(1);
  388.         }
  389.         return fp;
  390.     }
  391.  
  392.     fseek(gl, 2 + gl_fileno++ * 17, 0);
  393.     writelong(gl, gl_eof);
  394.     memset(fname, 0, 13);
  395.     strcpy(fname, name);
  396.     fwrite(fname, 13, 1, gl);
  397.     fseek(gl, gl_filestart = gl_eof + 4, 0);
  398.     return gl;
  399. }
  400.  
  401. int file_close(fp)
  402. FILE*   fp;
  403. {
  404.     if (!gl)
  405.         return fclose(fp);
  406.  
  407.     gl_eof = ftell(gl);
  408.     fseek(gl, gl_filestart - 4, 0);
  409.     writelong(gl, gl_eof - gl_filestart);
  410. }
  411.  
  412.  
  413.  
  414.